<template>
  <a-modal
    v-model:visible="dialogVisible"
    :title="title"
    :width="width"
    @cancel="handleCancel"
    @before-ok="handleBeforeOk"
  >
    <loading-spinner :visible="loading" text="提交中..." />

    <a-form ref="formRef" :model="modelValue" :rules="rules" label-align="left">
      <slot name="form-items" />
    </a-form>

    <template #footer>
      <slot name="footer">
        <a-space>
          <BaseButton type="outline" @click="handleCancel">取消</BaseButton>
          <BaseButton type="primary" :loading="loading" @click="handleBeforeOk"> 确定 </BaseButton>
        </a-space>
      </slot>
    </template>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import type { FormInstance } from '@arco-design/web-vue'
import type { FormDialogProps, FormDialogEmits } from '@/types/form-dialog'
import LoadingSpinner from './LoadingSpinner.vue'
import BaseButton from './BaseButton.vue'
import { useNotification } from '@/composables/useNotification'

const props = withDefaults(defineProps<FormDialogProps>(), {
  width: 630,
  loading: false,
  labelSpan: 24,
  wrapperSpan: 24,
  rules: () => ({}),
})

const emit = defineEmits<FormDialogEmits>()
const notify = useNotification()

const formRef = ref<FormInstance>()

const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val),
})

const handleCancel = () => {
  formRef.value?.resetFields()
  emit('cancel')
  emit('update:visible', false)
}

watch(
  () => props.visible,
  (newVal) => {
    if (!newVal) {
      formRef.value?.resetFields()
    }
  },
)

const handleBeforeOk = async () => {
  if (!formRef.value) {
    notify.error('表单实例不存在', {
      title: '验证失败',
    })
    return false
  }

  try {
    const errors = await formRef.value.validate()
    if (errors) {
      return false
    }
    return handleSubmit()
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : '表单验证失败'
    notify.error(errorMessage, {
      title: '验证失败',
    })
    return false
  }
}

const handleSubmit = async () => {
  try {
    await emit('submit')
    return true
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : '提交失败'
    notify.error(errorMessage, {
      title: '操作失败',
    })
    return false
  }
}

// 暴露方法给父组件使用
defineExpose({
  formRef,
})
</script>

<style scoped>
:deep(.arco-form-item-label) {
  font-weight: 500;
  color: var(--color-text-2);
}
</style>
